package tmt.usercenter.web.configure.security.bean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.session.HttpSessionDestroyedEvent;
import org.springframework.stereotype.Component;
import tmt.usercenter.web.domain.ClientSystem;
import tmt.usercenter.web.domain.LoginHistory;
import tmt.usercenter.web.domain.TmtUser;
import tmt.usercenter.web.domain.security.UserDetailsImpl;
import tmt.usercenter.web.service.ClientSystemService;
import tmt.usercenter.web.service.LoginAttemptService;
import tmt.usercenter.web.service.LoginHistoryService;

import javax.servlet.http.HttpServletRequest;

@Component
public class LoginEventListener implements ApplicationListener {

    @Autowired
    private LoginHistoryService loginHistoryService;

    @Autowired
    private ClientSystemService clientSystemService;

    @Autowired
    private LoginAttemptService loginAttemptService;

    @Autowired
    private HttpServletRequest httpServletRequest;

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof HttpSessionDestroyedEvent) {
            onEvent((HttpSessionDestroyedEvent) event);
        } else if (event instanceof AuthenticationFailureBadCredentialsEvent) {
            onEvent((AuthenticationFailureBadCredentialsEvent) event);
        } else if (event instanceof AuthenticationSuccessEvent) {
            onEvent((AuthenticationSuccessEvent) event);
        }
    }

    private void onEvent(AuthenticationSuccessEvent event) {
        try {
            Authentication token = event.getAuthentication();
            UserDetailsImpl details = (UserDetailsImpl) token.getPrincipal();
            loginAttemptService.loginSucceeded(details.getUsername());

            Long userId = details.getUserId();
            String clientId = details.getClientId();

            TmtUser user = new TmtUser();
            user.setId(userId);

            ClientSystem clientSystem = clientSystemService.findByClientId(clientId);

            if (userId != null && clientSystem != null) {
                String ipAddress = httpServletRequest.getRemoteAddr();
                if ("0:0:0:0:0:0:0:1".equals(ipAddress)) {
                    ipAddress = "127.0.0.1";
                }
                loginHistoryService.create(new LoginHistory(user, ipAddress, clientSystem));
            }
        } catch (Exception ex) {
        }
    }

    private void onEvent(AuthenticationFailureBadCredentialsEvent event) {
        try {
            UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) event.getAuthentication();
            loginAttemptService.loginFailed(token.getPrincipal().toString());
        } catch (Exception ex) {
        }
    }

    private void onEvent(HttpSessionDestroyedEvent event) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null) {
            UserDetailsImpl details = (UserDetailsImpl) auth.getPrincipal();
            Long userId = details.getUserId();
            String clientId = details.getClientId();
            loginHistoryService.userLogout(userId, clientId);
        }
    }
}